#include "book.h"
#include "protocol.h"
#include "tcpclient.h"
#include <QInputDialog>
#include <QMessageBox>
#include <QFileDialog>
#include <QProgressBar>
#include <QStandardPaths>
#include "opewidget.h"
#include "sharefile.h"

Book::Book(QWidget *parent)
    : QWidget{parent}
{
    m_bDownload = false;
    m_pBookListW = new QListWidget;
    // m_pBar = new mybar;
    // m_pBar->hide();

    m_pRetrunPB = new QPushButton("返回");
    m_pCreateDirPB = new QPushButton("创建文件夹");
    m_pDelDirPB = new QPushButton("删除文件夹");
    m_pRenamePB = new QPushButton("重新命名文件夹");
    m_pFlushFilePB = new QPushButton("刷新文件夹");
    m_pMoveFilePB = new QPushButton("移动文件");
    m_pSelectDirFilePB = new QPushButton("目标文件夹");
    m_pSelectDirFilePB->setEnabled(false);

    QVBoxLayout *pDirVBL = new QVBoxLayout;
    pDirVBL->addWidget(m_pRetrunPB);
    pDirVBL->addWidget(m_pCreateDirPB);
    pDirVBL->addWidget(m_pDelDirPB);
    pDirVBL->addWidget(m_pRenamePB);
    pDirVBL->addWidget(m_pFlushFilePB);
    pDirVBL->addWidget(m_pMoveFilePB);
    pDirVBL->addWidget(m_pSelectDirFilePB);

    m_pUploadPB = new QPushButton("上传文件夹");
    m_pDownLoadPB = new QPushButton("下载文件夹");
    m_pDelFilePB = new QPushButton("删除文件");
    m_pShareFilePB = new QPushButton("共享文件");

    QVBoxLayout *pFileVBL = new QVBoxLayout;
    pFileVBL->addWidget(m_pUploadPB);
    pFileVBL->addWidget(m_pDownLoadPB);
    pFileVBL->addWidget(m_pDelFilePB);
    pFileVBL->addWidget(m_pShareFilePB);
    //pFileVBL->addWidget(m_pBar);

    QHBoxLayout *pMain = new QHBoxLayout;
    pMain->addWidget(m_pBookListW);
    pMain->addLayout(pDirVBL);
    pMain->addLayout(pFileVBL);

    setLayout(pMain);

    //关联信号槽
    connect(m_pCreateDirPB, SIGNAL(clicked(bool)),this,SLOT(createDir()));
    connect(m_pFlushFilePB, SIGNAL(clicked(bool)),this,SLOT(flushFile()));
    connect(m_pDelDirPB, SIGNAL(clicked(bool)),this,SLOT(delDir()));
    connect(m_pRenamePB, SIGNAL(clicked(bool)),this,SLOT(renameFile()));
    connect(m_pBookListW, SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(enterDir(QListWidgetItem*)));
    connect(m_pRetrunPB, SIGNAL(clicked(bool)),this,SLOT(returnPreDir()));
    connect(m_pUploadPB, SIGNAL(clicked(bool)),this,SLOT(uploadFile()));
    connect(m_pDelFilePB, SIGNAL(clicked(bool)),this,SLOT(delfile()));
    connect(m_pDownLoadPB, SIGNAL(clicked(bool)),this,SLOT(downloadfile()));
    connect(m_pShareFilePB, SIGNAL(clicked(bool)),this,SLOT(shareFile()));
    connect(m_pMoveFilePB, SIGNAL(clicked(bool)),this,SLOT(moveFile()));
    connect(m_pSelectDirFilePB, SIGNAL(clicked(bool)),this,SLOT(selectDestDir()));
}

void Book::updateFileList(const PDU *pdu)
{
    if(NULL == pdu){
        return;
    }
    FileInfo *pFileInfo = NULL;
    int iCount = pdu->uiMsgLen / sizeof(FileInfo);
    m_pBookListW->clear();
    for(int i = 2; i < iCount; i++){
        pFileInfo = (FileInfo*)(pdu->caMsg) + i;
        qDebug()<<pFileInfo->caFileName<<pFileInfo->isFileType;
        QListWidgetItem *pItem = new QListWidgetItem;
        if(0 == pFileInfo->isFileType){
            pItem->setIcon(QIcon(QPixmap(":./image/dir.jpg")));
        }else{
            pItem->setIcon(QIcon(QPixmap(":./image/file.jpg")));
        }
        pItem->setText(pFileInfo->caFileName);
        m_pBookListW->addItem(pItem);
    }
}

void Book::setDownloadStatus(bool status)
{
    m_bDownload = status;
}

bool Book::getDownloadStatus()
{
    return m_bDownload;
}

void Book::createDir()
{
    QString strNewDir = QInputDialog::getText(this,"新建文件夹","名字");
    if(strNewDir.isEmpty()){
        QMessageBox::warning(this,"新建文件夹","名字不能为空");
        return;
    }
    if(strNewDir.size() > CADATEMAX){
        QMessageBox::warning(this,"新建文件夹","名字不能超过32个字符");
        return;
    }
    QString strName = TcpClient::getInstance().getloginName();
    QString strCurPath = TcpClient::getInstance().getCurPath();
    PDU *pdu = mkPDU(strCurPath.size() + 1);
    memcpy(pdu->caData,strName.toStdString().c_str(), strName.size());
    memcpy(pdu->caData + CADATEMAX,strNewDir.toStdString().c_str(), strNewDir.size());
    memcpy(pdu->caMsg,strCurPath.toStdString().c_str(), pdu->uiMsgLen);
    pdu->uiMsgType = ENUM_MSG_TYPE_CREATE_DIR_REQUEST;
    TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
    free(pdu);
    pdu = NULL;
}

void Book::flushFile()
{
    QString strCurPath = TcpClient::getInstance().getCurPath();
    PDU *pdu = mkPDU(strCurPath.size()+1);
    pdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_FILE_REQUEST;
    memcpy(pdu->caMsg, strCurPath.toStdString().c_str(), pdu->uiMsgLen);
    TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
    free(pdu);
    pdu = NULL;
}

void Book::delDir()
{
    QString strCurPath = TcpClient::getInstance().getCurPath();
    QListWidgetItem *pItem = m_pBookListW->currentItem();
    if(NULL == pItem){
        QMessageBox::warning(this,"删除文件夹","请选择要删除的文件夹");
    }else{
        QString strDelName = pItem->text();
        PDU *pdu = mkPDU(strCurPath.size() + 1);
        pdu->uiMsgType = ENUM_MSG_TYPE_DELETE_DIR_REQUEST;
        strncpy(pdu->caData,strDelName.toStdString().c_str(), strDelName.size());
        memcpy(pdu->caMsg, strCurPath.toStdString().c_str(), strCurPath.size());
        TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
        free(pdu);
        pdu = NULL;
    }
}

void Book::renameFile()
{
    QString strCurPath = TcpClient::getInstance().getCurPath();
    QListWidgetItem *pItem = m_pBookListW->currentItem();
    if(NULL == pItem){
        QMessageBox::warning(this,"重命名","请选择要重命名的文件");
    }else{
        QString strOldName = pItem->text();
        QString strNewName = QInputDialog::getText(this,"重命名","新名字");
        if(strNewName.isEmpty())
        {
            QMessageBox::warning(this,"重命名","新文件名不能为空");
            return;
        }
        PDU *pdu = mkPDU(strCurPath.size() + 1);
        pdu->uiMsgType = ENUM_MSG_TYPE_RENAME_DIR_REQUEST;
        strncpy(pdu->caData,strOldName.toStdString().c_str(), strOldName.size());
        strncpy(pdu->caData + CADATEMAX,strNewName.toStdString().c_str(), strNewName.size());
        memcpy(pdu->caMsg, strCurPath.toStdString().c_str(), strCurPath.size());
        TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
        free(pdu);
        pdu = NULL;
    }
}

void Book::enterDir(QListWidgetItem* caName)
{
    QString strDirName = caName->text();
    qDebug()<<strDirName;
    QString strCurPath = TcpClient::getInstance().getCurPath();
    PDU *pdu = mkPDU(strCurPath.size() + 1);
    pdu->uiMsgType = ENUM_MSG_TYPE_ENTER_DIR_REQUEST;
    strncpy(pdu->caData,strDirName.toStdString().c_str(), strDirName.size());
    memcpy(pdu->caMsg, strCurPath.toStdString().c_str(), strCurPath.size());
    TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
    free(pdu);
    pdu = NULL;
}

void Book::returnPreDir()
{
    QString strCurPath = TcpClient::getInstance().getCurPath();
    QString strRootPath = TcpClient::getInstance().getloginName();
    if(strCurPath == strRootPath){
        QMessageBox::warning(this,"返回","已经是根目录");
    }
    else
    {
        int index = strCurPath.lastIndexOf('/');
        strCurPath.remove(index,strCurPath.size()-index);
        TcpClient::getInstance().setCurPath(strCurPath);
        flushFile();
    }
}

void Book::uploadFile()
{
    QString strCurPath = TcpClient::getInstance().getCurPath();

    // 获取桌面路径作为默认路径
    QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);

    // 使用 QFileDialog 对象，允许选择文件或文件夹
    QFileDialog dialog(this);
    dialog.setWindowTitle("选择要上传的文件或文件夹");
    dialog.setDirectory(defaultPath);
    dialog.setFileMode(QFileDialog::ExistingFiles);  // 如果你要选择多个文件，或者：
    dialog.setOption(QFileDialog::ShowDirsOnly, false);  // 允许显示文件

    if (!dialog.exec()) {
        QMessageBox::warning(this, "上传", "未选择文件");
        return;
    }

    QStringList fileList = dialog.selectedFiles();
    if (fileList.isEmpty()) {
        QMessageBox::warning(this, "上传", "上传路径不能为空");
        return;
    }

    m_strUploadFilePath = fileList.at(0);  // 默认只取第一个
    QFileInfo info(m_strUploadFilePath);

    QString strFileName = info.fileName();  // 获取文件/目录名

    qint64 size = 0;
    if (info.isFile()) {
        QFile file(m_strUploadFilePath);
        size = file.size();
    } else if (info.isDir()) {
        // 如果是目录，这里可以实现递归统计总大小（可选）
        size = 0;  // 你可以在后续实现递归上传
    }

    m_iTotal = size;

    PDU *pdu = mkPDU(strCurPath.size() + 1);
    pdu->uiMsgType = ENUM_MSG_TYPE_UPLOAD_DIR_REQUEST;

    memcpy(pdu->caMsg, strCurPath.toStdString().c_str(), strCurPath.size());
    sprintf(pdu->caData, "%s %lld", strFileName.toStdString().c_str(), m_iTotal);

    TcpClient::getInstance().getTcpSocket().write((char *)pdu, pdu->uiPDULen);
    free(pdu);
    pdu = NULL;
}


void Book::uploadFileData()
{
    QFile file(m_strUploadFilePath);
    if(!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(this,"上传文件","打开文件失败");
        return;
    }
    char *pBuffer = new char[4096];
    qint64 ret = 0;
    while(true)
    {
        ret = file.read(pBuffer, 4096);
        if(ret > 0 && ret <= 4096)
        {
            TcpClient::getInstance().getTcpSocket().write(pBuffer,ret);
        }
        else if(0 == ret)
        {

            break;
        }
        else
        {
            QMessageBox::warning(this,"上传文件","上传文件失败：读文件失败");
            break;
        }
    }
    file.close();
    delete[] pBuffer;
    pBuffer = NULL;
}

void Book::showUploadFileDataProgress(qint64 isRecived)
{
    if(m_pBar->isHidden()){
        m_pBar->setPath(m_strUploadFilePath);
        m_pBar->show();
        qDebug()<<"展示进度条";
    }
    int newValue = int(isRecived/m_iTotal);
    m_pBar->setBarValue(newValue);
}

void Book::hideBar()
{
    flushFile();
    m_pBar->hide();
    m_pBar->setPath("");
    m_pBar->setBarValue(0);
}

void Book::delfile()
{
    QString strCurPath = TcpClient::getInstance().getCurPath();
    QListWidgetItem *pItem = m_pBookListW->currentItem();
    if(NULL == pItem){
        QMessageBox::warning(this,"删除文件","请选择要删除的文件");
    }else{
        QString strDelName = pItem->text();
        PDU *pdu = mkPDU(strCurPath.size() + 1);
        pdu->uiMsgType = ENUM_MSG_TYPE_DELETE_FILE_REQUEST;
        strncpy(pdu->caData,strDelName.toStdString().c_str(), strDelName.size());
        memcpy(pdu->caMsg, strCurPath.toStdString().c_str(), strCurPath.size());
        TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
        free(pdu);
        pdu = NULL;
    }
}

void Book::downloadfile()
{
    QListWidgetItem *pItem = m_pBookListW->currentItem();
    if(NULL == pItem){
        QMessageBox::warning(this,"下载文件","请选择下载文件");
    }else
    {
        QString strCurPath = TcpClient::getInstance().getCurPath();
        PDU *pdu = mkPDU(strCurPath.size() + 1);
        pdu->uiMsgType = ENUM_MSG_TYPE_DOWNLOAD_DIR_REQUEST;
        QString strFileName = pItem->text();
        strcpy(pdu->caData, strFileName.toStdString().c_str());
        memcpy(pdu->caMsg,strCurPath.toStdString().c_str(),pdu->uiMsgLen);


        QString strSaveFilePath = QFileDialog::getSaveFileName();
        if(strSaveFilePath.isEmpty())
        {
            QMessageBox::warning(this,"下载文件","请指定下载的路径");
            m_strSaveFilePath.clear();
        }
        else
        {
            m_strSaveFilePath = strSaveFilePath;
            //m_bDownload = true;
        }
        TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
        free(pdu);
        pdu = NULL;
    }
}

void Book::shareFile()
{
    QListWidgetItem *pItem = m_pBookListW->currentItem();
    if(NULL == pItem){
        QMessageBox::warning(this,"分享文件","请选择要分享的文件");
        return;
    }
    else
    {
        m_strSaveFilePath = pItem->text();
    }
    Friend *pFriend = OpeWidget::getInstance().getFriend();
    pFriend->flushFriend();
    QListWidget *pFriendList = pFriend->getFriendList();
    // for(int i = 0; i < pFriendList->count(); i++){
    //     qDebug() <<pFriendList->item(i)->text();
    // }

    if(ShareFile::getInstance().isHidden()){
        ShareFile::getInstance().show();
    }
    ShareFile::getInstance().updateFriend(pFriendList);

}

void Book::moveFile()
{
    QListWidgetItem *pItem = m_pBookListW->currentItem();
    if(NULL == pItem){
        QMessageBox::warning(this,"移动文件","请选择要移动的文件");
        return;
    }
    else
    {
        m_strMoveFileName = pItem->text();
        QString strCurPath = TcpClient::getInstance().getCurPath();
        m_strMoveFilePath = strCurPath + '/' + m_strMoveFileName;
        m_pSelectDirFilePB->setEnabled(true);

    }
}

void Book::selectDestDir()
{
    QListWidgetItem *pItem = m_pBookListW->currentItem();
    if(NULL == pItem){
        QMessageBox::warning(this,"移动文件","请选择要移动的目的文件夹");
        return;
    }
    else
    {
        QString strDestDir = pItem->text();
        QString strCurPath = TcpClient::getInstance().getCurPath();
        m_strDestDir = strCurPath + '/' + strDestDir;
        int srcLen = m_strMoveFilePath.size();
        int destLen = m_strDestDir.size();
        PDU *pdu = mkPDU(srcLen + destLen + 2);
        pdu->uiMsgType = ENUM_MSG_TYPE_MOVE_FILE_REQUEST;
        sprintf(pdu->caData,"%d %d %s",srcLen,destLen,m_strMoveFileName.toStdString().c_str());
        memcpy(pdu->caMsg, m_strMoveFilePath.toStdString().c_str(),srcLen);
        memcpy((pdu->caMsg) + srcLen+ 1, m_strDestDir.toStdString().c_str(),destLen);
        TcpClient::getInstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
        free(pdu);
        pdu = NULL;
    }
    m_pSelectDirFilePB->setEnabled(false);
}


